import superService from "./services/superService";
import localStorageService from "./services/localStorageService";
import superManager from "./managers/superManager";
import soundManager from "./managers/soundManager";
import ossService from "./services/ossService";
import miniGameService from "./services/miniGameService";
import userService from "./services/userService";
import gameManager from "./managers/gameManager";
import GameManager from "./managers/gameManager";
import uiModule from "./modules/uiModule";
import GameHttpModule from "./modules/gameHttpModule";
import gameWebSocketModule from "./modules/gameWebSocketModule";
import LogService from "./services/logService";
import {GameEvent} from "./configs/engineConfig";
import mainRoot from "../Game/MainRoot";
import ziManager from "./managers/ziManager";
import peopleArcheryManage from "./managers/peopleArcheryManage";
import CsvDataManage from "./managers/CsvDataManage";
import goldMinerManager from "./managers/goldMinerManager";


interface Modules {
    uiControlModule: uiModule,
    gameHttpModule: GameHttpModule,
    gameWebsocketModule: gameWebSocketModule,
}

interface Services {
    localStorageSrv: localStorageService,
    logSrv: LogService,
    ossSrv: ossService,
    miniGameSrv: miniGameService,
    userSrv: userService,
}

interface Managers {
    soundMgr: soundManager,
    gameMgr: gameManager,
    ziMgr:ziManager,
    csvDataManager:CsvDataManage,
    peopleArcheryManager:peopleArcheryManage,
    goldMinerManager:goldMinerManager,
}

export function services() {
    return O1HD.getServices();
}

export function managers() {
    return O1HD.getManagers();
}

export function modules() {
    return O1HD.getModules();
}

class gameEngine {
    protected services: Services;
    protected managers: Managers;
    protected m_modules: Modules;

    constructor() {
        //模块
        this.m_modules = {
            uiControlModule: new uiModule(),
            gameHttpModule: new GameHttpModule(),
            gameWebsocketModule: new gameWebSocketModule(),
        };
        //服务
        this.services = {
            localStorageSrv: new localStorageService(),
            ossSrv: new ossService(),
            miniGameSrv: new miniGameService(),
            userSrv: new userService(),
            logSrv: new LogService(),
        }
        //管理
        this.managers = {
            soundMgr: new soundManager(),
            gameMgr: new GameManager(),
            ziMgr:new ziManager(),
            csvDataManager:new CsvDataManage(),
            peopleArcheryManager:new peopleArcheryManage(),
            goldMinerManager:new goldMinerManager(),
        }
        // console.log('<游戏主框架>');
        //重写部分API
        this.reDefinedApi();
    }

    getModules(): Modules {
        return this.m_modules;
    }

    getManagers() {
        return this.managers;
    }

    getServices() {
        return this.services;
    }

    async loadAll(): Promise<void> {
        // console.log('■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■');
        // console.log(COMPANY_COPY);
        // console.log('@version', CODE_VERSION);
        // console.log('@time', FRAME_TIME);
        // console.log('@copy', COMPANY_NAME);
        // console.log('■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■');

        //加载
        // const startTime = Date.now();
        // let t = startTime;
        // console.log('★★★★★框架载入★★★★★');

        //模块
        // console.log(`${LINE_SPLIT_START_LEFT}加载所有模块${LINE_SPLIT_START_RIGHT}`);
        await O1HD.loadAllModules();
        // console.log(`${LINE_SPLIT_END_LEFT}所有模块已载${LINE_SPLIT_END_RIGHT}`, Date.now() - t, 'ms');
        // t = Date.now();

        //先加载oss服务 因为配置在里面
        // console.log(`${LINE_SPLIT_START_LEFT}加载OSS服务${LINE_SPLIT_START_RIGHT}`);
        await this.getServices().ossSrv.loadService();
        // console.log(`${LINE_SPLIT_END_LEFT}OSS服务已载${LINE_SPLIT_END_RIGHT}`, Date.now() - t, 'ms');
        await this.getServices().ossSrv.onLoadedService();
        // t = Date.now();

        //服务
        // console.log(`${LINE_SPLIT_START_LEFT}加载所有服务${LINE_SPLIT_START_RIGHT}`);
        await this.loadServices();
        // console.log(`${LINE_SPLIT_END_LEFT}所有服务已载${LINE_SPLIT_END_RIGHT}`, Date.now() - t, 'ms');
        // t = Date.now();

        //管理
        // console.log(`${LINE_SPLIT_START_LEFT}加载所有管理${LINE_SPLIT_START_RIGHT}`);
        await this.loadManagers();
        // console.log(`${LINE_SPLIT_END_LEFT}所有管理已载${LINE_SPLIT_END_RIGHT}`, Date.now() - t, 'ms');
        // t = Date.now();

        // console.log('★★★★★框架完毕★★★★★', Date.now() - startTime, 'ms (总耗时)');
        await mainRoot.GameInit();
        return Promise.resolve();
    }

    emit(event: string, ...args) {
        this.Canvas().emit(event, ...args);
    }


    on(event: string, callback: (...args: any[]) => void, target? : any) {
        this.Canvas().on(event, callback, target);
    }

    off(event: string, callBack?: (...pram) => void, target ?: any) {
        this.Canvas().off(event,callBack,target);
    }
    once(event: string, callback: () => void, ...args) {
        this.Canvas().once(event, callback, ...args);
    }

    /**
     * return {cc.Component} 当前场景画布挂载的脚本
     * */
    Component(): cc.Component {
        return this.Canvas().getComponent(cc.Component);
    }

    /**
     * @return {cc.Node} 当前场景的画布节点
     * */
    Canvas(): cc.Node {
        return cc.find('Canvas');
    }

    /**
     * 释放没使用资源
     */
    releaseUnusedAssets() {
        try {
            //@ts-ignore
            cc.resources.releaseUnusedAssets();
        } catch (e) {
            console.warn('#498 警告 res unused release', e);
        }
    }

    //切换场景
    changeScene(sceneName: string, successCallback?: () => void) {
        this.loadScene(sceneName, successCallback);
    }

    //加载并切换场景
    loadScene(sceneName: string, successCallback?: () => void) {
        // console.error("更换场景")
        O1HD.emit(GameEvent.CHANGE_SCENE_BEFORE);
        cc.director.loadScene(sceneName, () => {
            O1HD.emit(GameEvent.CHANGE_SCENE_AFTER);
            this.services && this.services.miniGameSrv.getAppApiInstance && this.services.miniGameSrv.getAppApiInstance() && this.services.miniGameSrv.getAppApiInstance().WidgetfullScreen && this.services.miniGameSrv.getAppApiInstance().WidgetfullScreen()  //屏幕适配
            successCallback && successCallback();
        });
    }

    private async loadAllModules() {
        //先预加载
        for (let key in this.m_modules) {
            await this.m_modules[key].preLoadModules();
        }
        //再加载
        for (let key in this.m_modules) {
            await this.m_modules[key].loadModule();
            await this.m_modules[key].onLoadedModule();
        }
        return Promise.resolve();
    }

    private reDefinedApi() {
    }

    private async loadManagers() {
        for (let k in this.managers) {
            let mgr: superManager = this.managers[k];
            await mgr.loadManager();
            await mgr.onLoadedManager();
        }
    }

    private async loadServices() {
        for (let k in this.services) {
            let srv: superService = this.services[k];
            if (!srv.isLoaded()) {
                await srv.loadService();
                await srv.onLoadedService();
            }
        }
    }
}

//引擎主入口
function main(): gameEngine {
    try {
        window['O1HD'] = new gameEngine();
        return window['O1HD'];
    } catch (e) {
        console.error('主引擎创建失败', e);
    }
}

let O1HD: gameEngine = main();

export default O1HD;

// export function main() {
//     try {
//         if (null == O1HD) {
//             O1HD = new gameEngine();
//         }
//     } catch (e) {
//         console.error('游戏主引擎创建失败', e);
//     }
// }
//
// let O1HD: gameEngine = null;
//
// export default O1HD;